// english_words_reit.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <ksfilefunc/ksfilefunc.h>
#include <ksstr/ksstr.h>

using  std::cout;
using  std::cerr;
using  std::endl;
using  std::string;
using  std::vector;

#include <sstream>
#include <algorithm>

#define MAX_WORD_LEN  22

void log_msg(const char* msg)
{
	//cout << "LOG: " <<  msg << endl;

}

size_t search_word(const vector<string>& words, const string& word)
{
	for(size_t c=0; c<words.size(); c++)
	{
		if( word == words[c] )
		{
			return c;
		}
	}
 
	return 0-1;
}

void print_lines( vector<string>& lines )
{
	for(size_t c=0; c<lines.size(); c++)
	{
		cout << lines[c] << "\n";
	}

}


void  __cdecl  OnFoundFile( const CHAR* lpszFileName, void* pUserData )
{
	vector<string>* filenames = (vector<string>*)pUserData;
	filenames->push_back( string(lpszFileName) );

	//assert(0);
	int _end =0;
}

void search_files(vector<string>& filenames, const string& dir)
{
	char temp [200];
	temp[0] = 0;
	strcpy(temp, dir.c_str());
	strcat(temp, "*.txt");

	ksfilefunc::searchFilesA(temp, OnFoundFile, (void*)&filenames  , TRUE);
}


//==============================================
bool load_text(std::string& dest,   const char* fname)  
{
	dest = "";
	FILE* file = fopen(fname, "r");
	if(!file) return false;

	size_t filesize = ksfilefunc::getFileSizeStd(file);
	int bufsize = filesize + 1000;
	char* buf = new char[ bufsize ];
	memset(buf, 0, bufsize);
	fread(buf, 1, filesize, file );

	//  preprocess
	for(size_t c=0; c<filesize; c++)
	{
		if( buf[c]=='\0' )
		{
			//if(buf[c+1]!='\0')
			//{
			//
			//}
			//}
			buf[c]= ' ';


		}	
	}

	dest = buf;
	delete [] buf;
	fclose(file);
	return true;
}


void read_all_text( vector<string>& dest_texts, vector<string>& filenames)
{
	string curr_text;
	for(size_t c=0; c<filenames.size(); c++)
	{
		const string& fname = filenames[c];
		if( !load_text(curr_text, fname.c_str()) )
		{
			cerr << "Errro read file \n";
			exit(-1);
		}

		if(curr_text.length() ) 
		{
			dest_texts.push_back(curr_text);
		}
	}

}

void make_single_text(string& dest_text, vector<string>& items)
{
	dest_text = "";
	for(size_t c=0; c<items.size(); c++)
	{
		dest_text +=    items[c].c_str();  //items[c];  
		dest_text += "\n"; 
	}
}


struct word_s
{
	unsigned int count;
	string line;

	word_s()
	{
		count = 1;
	}

	word_s(const string& w)
	{
		count = 1;
		line = w;
	}
};

bool is_word_separator(char cr)
{
	if(cr=='`') return false;

   return  !ksstr::isLatinLetter(cr);
}

bool is_word_valid(const string& word)
{
	if(word.length()==0) return false;

	if(word.length()==1)
	{
		if( (word[0]=='a')||(word[0]=='i')||(word[0]=='u') ) return true;
		return false;
	}

	if(word.length() > MAX_WORD_LEN) return false;

	return true;
}

void splitwords(vector<word_s>& dest, const string& text, unsigned int& found_count)
{
	found_count = 0;
	string new_word;
	for(size_t c=0; c<text.length(); c++)
	{
		const char curr = tolower(text[c]);

		if(	 is_word_separator(curr)

			//(curr==';')||(curr==',')||(curr==' ')||(curr=='\n')||(curr=='\t')||(curr=='=')||(curr=='+')||
			//(curr==10)||(curr=='/')||(curr=='\\')||(curr=='.')||(curr=='!')||(curr=='&')||(curr=='\'')||(curr=='\"')||
			//(curr==':')||(curr=='-')||(curr=='(')||(curr==')')


			)
		{
			if( (new_word.length()) && ( is_word_valid(new_word) ) )
			{
				// new word !
				found_count++;
				//cout << "found word: " << found_count << "  " << new_word << endl;
				bool need_add = true;
				while(true)
				{
 
					for(size_t j=0; j<dest.size(); j++)
					{
						const string& aitem = dest[j].line;
						if(aitem == new_word)
						{
							// found !
							dest[j].count++;
							need_add = false;
							break;
						}
					}

					if(need_add)
					{
						if(new_word.length() > MAX_WORD_LEN)
						{
							log_msg("big word");
						}

						dest.push_back( word_s( new_word ) );
					}

					new_word = "";

					break;
				} // while(true)



			} // if( new_word.length() )

			

			continue;
		} // if

		new_word += tolower(curr);

		if(new_word.length() > MAX_WORD_LEN)
		{
			log_msg("big word");
		}



	}

	//if( item.length() )
	//{
	//	if (search_word(dest, item) == -1)
	//	{
	//		dest.push_back(item);
	//		item = "";
	//	}

	//}

}

bool OnSordWord(const word_s& a1, const word_s& a2)
{
	return a1.count > a2.count;
}

void sortwords(vector<word_s>& words)
{
	std::sort( words.begin(), words.end(), OnSordWord );
}

void print_lines( vector<word_s>& lines )
{
	for(size_t c=0; c<lines.size(); c++)
	{
		cout << lines[c].count << "  " << lines[c].line << "\n";
	}
}

void make_report(const vector<string>& src_file_names, int found_count, int num_words,  const vector<word_s>& lines )
{
	string text;
   std::stringstream temp;
   
   for(size_t c=0; c<src_file_names.size(); c++)
   {
	   temp << "src file names: " << src_file_names[c] << endl;

   }

   temp << "\n\n";

   temp << "found count: " << found_count << endl;
   temp << "num words: " << num_words << "\n\n\n";

   text += temp.str();

	for(size_t c=0; c<lines.size(); c++)
	{
		std::stringstream ss;
		ss << lines[c].count << "  " << lines[c].line << "\n";
		text += ss.str();
	}

	ksstr::saveStrToFileA(text, "c:/temp/report.txt");
}
 


//==================================================
 

int _tmain(int argc, _TCHAR* argv[])
{
 


	string start_dir = "c:/temp/eng_text/";
	vector<string> textfilenames;
	search_files(textfilenames, start_dir);

	cout << "Found " << textfilenames.size() << " files! \n";
 

	vector<string> dest_texts;
	read_all_text(dest_texts, textfilenames);


	

	string single_text;
	make_single_text(single_text, dest_texts);

	cout << "Single text len: " << single_text.length() << endl;
	


	vector<word_s> words;
	unsigned int found_count = 0;
	splitwords(words, single_text, found_count);
	cout << "found_count: " << found_count << "\n";
 


	cout << "Sort words by usage \n";
	sortwords(words);


	print_lines(words);
	cout << " words= " << words.size() << endl;


	make_report( textfilenames, found_count, words.size(), words);
	cout << "\n\n  MAKE REPORT COMPLETE !   \n\n"  ;

	system("pause");
	return 0;
}

